package com.github.kazuki43zoo.api.error; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; import org.springframework.validation.BindingResult; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import org.terasoluna.gfw.common.exception.BusinessException; import org.terasoluna.gfw.common.exception.ExceptionCodeResolver; import org.terasoluna.gfw.common.exception.ResourceNotFoundException; import org.terasoluna.gfw.common.exception.ResultMessagesNotificationException; import javax.inject.Inject; @ControllerAdvice public class ApiGlobalExceptionHandler extends ResponseEntityExceptionHandler { @Inject ApiErrorCreator apiErrorCreator; @Inject ExceptionCodeResolver exceptionCodeResolver; @Override protected ResponseEntity<Object> handleExceptionInternal(final Exception ex, final Object body, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { final Object apiError; if (body == null) { String errorCode = exceptionCodeResolver.resolveExceptionCode(ex); apiError = apiErrorCreator.createApiError(request, errorCode, ex.getLocalizedMessage()); } else { apiError = body; } return new ResponseEntity<>(apiError, headers, status); } @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { return handleBindingResult(ex, ex.getBindingResult(), headers, status, request); } @Override protected ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { return handleBindingResult(ex, ex.getBindingResult(), headers, status, request); } @Override protected ResponseEntity<Object> handleHttpMessageNotReadable(final HttpMessageNotReadableException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { if (ex.getCause() instanceof Exception) { return handleExceptionInternal((Exception) ex.getCause(), null, headers, status, request); } else { return handleExceptionInternal(ex, null, headers, status, request); } } @ExceptionHandler public ResponseEntity<Object> handleResourceNotFoundException(final ResourceNotFoundException ex, final WebRequest request) { return handleResultMessagesNotificationException( ex, null, HttpStatus.NOT_FOUND, request); } @ExceptionHandler public ResponseEntity<Object> handleBusinessException(final BusinessException ex, final WebRequest request) { return handleResultMessagesNotificationException(ex, null, HttpStatus.CONFLICT, request); } @ExceptionHandler public ResponseEntity<Object> handleConcurrencyFailureException(final ConcurrencyFailureException ex, WebRequest request) {return handleExceptionInternal(ex, null, null, HttpStatus.CONFLICT, request); } @ExceptionHandler public ResponseEntity<Object> handleSystemError(final Exception ex, final WebRequest request) { return handleExceptionInternal(ex, null, null, HttpStatus.INTERNAL_SERVER_ERROR, request); } private ResponseEntity<Object> handleBindingResult(final Exception ex, final BindingResult bindingResult, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { final String errorCode = exceptionCodeResolver.resolveExceptionCode(ex); final ApiError apiError = apiErrorCreator.createBindingResultApiError(request, errorCode, bindingResult, ex.getMessage()); return handleExceptionInternal(ex, apiError, headers, status, request); } private ResponseEntity<Object> handleResultMessagesNotificationException(final ResultMessagesNotificationException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { final String errorCode = exceptionCodeResolver.resolveExceptionCode(ex); final ApiError apiError = apiErrorCreator.createResultMessagesApiError(request, errorCode, ex.getResultMessages(), ex.getMessage()); return handleExceptionInternal(ex, apiError, headers, status, request); } }